package com.aloda.aop;

import com.alibaba.fastjson.JSONObject;
import com.aloda.annotation.OperateLogAnno;
import com.aloda.context.AdminBaseContext;
import com.aloda.entity.Emp;
import com.aloda.entity.OperateLog;
import com.aloda.mapper.EmpMapper;
import com.aloda.mapper.OperateLogMapper;
import jakarta.annotation.Resource;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;
import java.util.Arrays;

@Aspect
@Component
public class OperateLogAspect {

    @Resource
    private OperateLogMapper operateLogMapper;

    @Resource
    private EmpMapper empMapper;

    /**
     * 日志记录
     * @param joinPoint
     * @param operateLogAnno
     * @return
     */
    @Around("@annotation(operateLogAnno)")
    public Object writeOperateLog(ProceedingJoinPoint joinPoint, OperateLogAnno operateLogAnno) throws Throwable {
        // 获取当前用户
        Long currentId = AdminBaseContext.getCurrentId();
        Emp emp = empMapper.selectById(currentId);
        //获取操作时间
        LocalDateTime time = LocalDateTime.now();
        //获取操作类名
        String className = joinPoint.getTarget().getClass().getName();
        String shortClassName = className.substring(className.lastIndexOf(".")+1);
        //获取操作的方法名
        String methodName = joinPoint.getSignature().getName();
        //操作方法的参数
        Object[] args = joinPoint.getArgs();
        String methodParams = Arrays.toString(args);
        long begin = System.currentTimeMillis();
        //调用原始目标方法运行
        Object result = joinPoint.proceed();
        long end = System.currentTimeMillis();
        //方法返回值
        String returnValue = JSONObject.toJSONString(result);
        //操作耗时
        long costTime=end-begin;
        OperateLog operateLog = new OperateLog();
        operateLog.setEmpId(currentId);
        operateLog.setEmpName(emp.getEmpName());
        operateLog.setOpTime(time);
        operateLog.setClassName(shortClassName);
        operateLog.setMethodName(methodName);
        operateLog.setMethodParams(methodParams);
        operateLog.setReturnValue(returnValue);
        operateLog.setCostTime(costTime);
        operateLog.setCategory(operateLogAnno.category());
        // 记录日志
        operateLogMapper.insert(operateLog);

        return result;
    }
}
